package cn.amoqi.springboot.redis.controller;

import cn.amoqi.springboot.redis.entity.Student;
import cn.amoqi.springboot.redis.subscriptions.MessagePublisher;
import cn.amoqi.springboot.redis.task.RedisDelayedQueue;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.task.TaskExecutor;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.PostConstruct;
import java.util.concurrent.TimeUnit;

/**
 * @Description: index
 * @author: zhuiFeng
 * @date: 2021年02月27日 9:57
 */
@RestController
@Slf4j
public class IndexController {

    final RedissonClient redissonClient;

    final TaskExecutor taskExecutor;

    public IndexController(RedissonClient redissonClient,TaskExecutor taskExecutor) {
        this.redissonClient = redissonClient;
        this.taskExecutor = taskExecutor;
    }

    @Value("${spring.redis.host}")
    private String host;

    @Value("${spring.redis.port}")
    private String port;


    @RequestMapping("")
    public String init11(){
        return host+":"+port;
    }

    @Autowired
    RedisDelayedQueue redisDelayedQueue;
    @Autowired
    private MessagePublisher messagePublisher;

    @PostConstruct
    public void initTask(){
        /*RedisDelayedQueue.TaskEventListener<Student> taskEventListener = new RedisDelayedQueue.TaskEventListener<Student>() {
            @Override
            public void invoke(Student taskBodyDTO) {
                //这里调用你延迟之后的代码
                log.info("执行...." + taskBodyDTO.getName() + "===" + taskBodyDTO.getAge());
            }
        };*/
        /*实现线程池进行处理*/
        //taskExecutor.execute(()->redisDelayedQueue.run(Student.class, taskEventListener));
        /*新建一个线程进行处理*/
        //new Thread(()->redisDelayedQueue.run(Student.class, taskEventListener)).start();

        /*使用java8函数的方法*/
        new Thread(()->redisDelayedQueue.run(Student.class,x-> System.out.println("执行...." + JSON.toJSONString(x) + "==="))).start();
    }


    @RequestMapping("ps")
    public String testPublisherAndSubscriber(){
        messagePublisher.send("给你发消息");
        return "TTTT...YYYY";
    }

    /**
     * 测试Redis定时任务
     * @return
     */
    @RequestMapping("/task")
    public String taskTest(){
        Student student1 = new Student("zhangsan",20);
        redisDelayedQueue.addQueue(student1,20L,TimeUnit.SECONDS);

        Student student2 = new Student("zhangsan",21);
        redisDelayedQueue.addQueue(student2,21L,TimeUnit.SECONDS);

        Student student3 = new Student("zhangsan",22);
        redisDelayedQueue.addQueue(student3,22L,TimeUnit.SECONDS);

        Student student4 = new Student("zhangsan",23);
        redisDelayedQueue.addQueue(student4,23L,TimeUnit.SECONDS);
        return "task";
    }

    /**
     * 测试redission锁
     * @return
     */
    @RequestMapping("/redissionClient")
    public String init(){
        RLock lock = redissonClient.getLock("name");
        System.out.println(Thread.currentThread().getId());
        try {
            int i = 0;
            System.out.println(Thread.currentThread());
            /*waitTime:尝试获取锁的时间，leaseTime：释放锁的时间 TimeUnit:时间的单位*/
            while (!lock.tryLock(50,50002, TimeUnit.MILLISECONDS)){
                i++;
                lock = redissonClient.getLock("name"+i);
            }
            System.out.println("获取到lock"+lock.getName());
            System.out.println("执行业务");
            try {
                boolean locked = lock.isLocked();
                System.out.println("是否正在锁："+locked);
                TimeUnit.SECONDS.sleep(5);
                locked = lock.isLocked();
                System.out.println("是否正在锁："+locked);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            System.out.println("释放锁");
            if(lock.isHeldByCurrentThread()){
                lock.unlock();
            }
        }
        return "777777";
    }
}
